<?php

namespace App\Crontab;

use App\Model\Novel;
use App\Model\NovelChapter;
use Carbon\Carbon;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\Coroutine\WaitGroup;
use Hyperf\Crontab\Annotation\Crontab;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use QL\QueryList;
use Swoole\Timer;
use function Hyperf\Coroutine\co;

//#[Crontab(rule: "* */10 * * * *", name: "novel", callback: "execute", memo: "小说抓取脚本")]
class NovelCrontab
{
    #[Inject]
    private StdoutLoggerInterface $logger;

    public function execute()
    {
        //需要统一抓取的放在这里面执行
        //获取小说
        //$this->getLists();
        //获取小说章节
        //$this->get_novel_chapter();
        //获取小说内容
        //$this->get_novel_connect();
    }

    public function isEnable(): bool
    {
        return true;
    }

    /**
     * 小说分类
     * @return void
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    //#[Crontab(rule: "0 */30 * * * *", name: "novel_category", callback: "execute", memo: "小说分类")]
    public function getClassify()
    {
        $time = getMillisecondTimestamp();
        $token =generateCSRFToken();
        $url = "https://www.xs8.cn/ajax/user/info?_csrfToken={$token}&_={$time}";
        $data = http_pool_curl($url);
        if (is_array($data)){
            if ($data['code']==0){
                $data_array = $data['data']['catInfo'];
                if ($data_array){
                    $add=[];
                    foreach ($data_array as $value){
                        $catId = $value['catId'];
                        $catName = $value['catName'];
                        $this->logger->info("{$catId}: {$catName} 抓取");
                        $add[]=[
                            'cat_id'=>$catId,
                            'cat_name'=>$catName
                        ];
                    }
                    //写入数据表

                }
            }
        }
    }


    /**
     * 获取小说列表
     * @return void
     */
    private function getLists()
    {
        $cat_array=[30013,30036.30020,30031,30001,30008,30042,30050,30055,30083];
        //$cat_count = count($cat_array);
        //for ($j=0;$j<$cat_count;$j++){
            //$cat_id=$cat_array[$j];
            $cat_id=$cat_array[array_rand($cat_array)];
            $count=50;
            $wg = new WaitGroup();
            $wg->add($count);
            for ($i=$count;$i>0; $i--){
                co(function ()use($cat_id,$i,$wg){
                    $platform = "言情小说吧";
                    $url="https://www.xs8.cn/category/{$cat_id}_f1_f1_f1_f1_f1_0_{$i}";
                    // 元数据DOM解析规则
                    $rules = [
                        //小说封面
                        'img' => ['.book-img>a>img','src'],
                        //小说链接
                        'url' => ['.book-img>a','href'],
                        // 小说标题
                        'name' => ['.book-info>h3','text'],
                        // 作者
                        'author' => ['.book-info>h4>a','text'],
                        // 类型
                        'classify' => ['.book-info>.tag>.org','text'],
                        //是否连载
                        'overall_novel' => ['.book-info>.tag>.pink','text'],
                        //字数
                        'number_words' => ['.book-info>.tag>.blue','text'],
                        // DOM解析文章内容
                        'brief_introduction' => ['.book-info>.intro','text'],
                    ];
                    // 切片选择器
                    $range = '.right-book-list li';
                    //获取到的页面数据
                    $data = QueryList::get($url)->range($range)->rules($rules)->query()->getData()->all();
                    $add=[];
                    if ($data){
                        foreach ($data as $value){
                            $info = Db::table('novel')->where(['platform'=>$platform,'classify'=>$value['classify'],'name'=>$value['name'],'author'=>$value['author']])->first();
                            if (!$info){
                                $add_insert['platform']=$platform;
                                $add_insert['classify']=$value['classify'];
                                $add_insert['name']=$value['name'];
                                $add_insert['author']=$value['author'];
                                $add_insert['url']="https://www.xs8.cn".$value['url'];
                                $add_insert['img']=$value['img'];
                                $add_insert['overall_novel']=$value['overall_novel'];
                                $add_insert['number_words']=$value['number_words'];
                                $add_insert['brief_introduction']=$value['brief_introduction'];
                                $add[]=$add_insert;
                            }else{
                                $update['img']=$value['img'];
                                $update['overall_novel']=$value['overall_novel'];
                                $update['number_words']=$value['number_words'];
                                Db::table('novel')->where('id',$info['id'])->update($update);
                            }
                        }
                    }
                    if ($add){
                        Db::table('novel')->insert($add);
                    }
                    $wg->done();
                });
            }
            // 等待协程 A 和协程 B 运行完成
            $wg->wait();
        //}
    }

    /**
     * 获取小说章节
     * @return void
     */
    protected function get_novel_chapter()
    {
        $timer_id = Timer::tick(30000,function ()use(&$timer_id){
            static $i=0;
            $limit=20;
            $offset=$i*$limit;
            $novel_id_max = NovelChapter::max('novel_id')??0;
            $data= Novel::query()->where(['status'=>0])->where('id','>',$novel_id_max)->offset($offset)->limit($limit)->get();
            if (empty($data)){
                Timer::clear($timer_id);
                return "ok";
            }
            foreach ($data as $value){
                $url = $value['url'];
                $novel_id = $value['id'];
                $data_query = QueryList::get($url);
                //获取到的页面数据
                // DOM解析文章标题
                $names = $data_query->find('.volume-wrap>.volume>.cf>li>a')->texts();
                // DOM解析文章作者
                $urls = $data_query->find('.volume-wrap>.volume>.cf>li>a')->attrs('href');
                $add=[];
                $count = count($names);
                for ($j=0;$j<$count;$j++){
                    $info = NovelChapter::query()->where(['novel_id'=>$novel_id,'name'=>$names[$j]])->first();
                    if (!$info){
                        $add[]=['name'=>$names[$j],'url'=>"https://www.xs8.cn".$urls[$j],'novel_id'=>$novel_id,'chapter_number'=>($j+1)];
                    }
                }
                if ($add){
                        NovelChapter::insert($add);
                }
            }
            $i++;
            return 'ok';
        });
    }

    /**
     * 获取小说的内容
     * @return void
     */
    protected function get_novel_connect()
    {
        $timer_id = Timer::tick(30000,function ()use(&$timer_id){
            static $i=0;
            $limit=100;
            $offset=$i*$limit;
            $id_max = NovelChapter::whereNull('content')->min('id')??0;
            $data= NovelChapter::query()->where(['status'=>0])->where('id','>',$id_max)->whereNull('content')->offset($offset)->limit($limit)->get();
            if (empty($data)){
                Timer::clear($timer_id);
                return 'ok';
            }
            foreach ($data as $value){
                $id = $value['id'];
                $url = $value['url'];
                $data_query = QueryList::get($url);
                //内容解析
                $connect_number = $data_query->find('.info>i:eq(0)>.j_chapterWordCut')->text();
                $connect_time = $data_query->find('.info>i:eq(1)>.j_updateTime')->text();
                $connect = $data_query->find('.j_readContent>.ywskythunderfont>p')->text();
                $strlen = strlen($connect);
                $new_connect = substr($connect,0,strrpos($connect ,"window.fkp"));
                if ($new_connect<=$strlen){
                    $update['is_complete']=1;
                }
                $update['number_words']=$connect_number;
                $update['content']=$new_connect;
                $update['updated_at']=$connect_time;
                $update['created_at']=date("Y-m-d H:i:s");
                NovelChapter::query()->where('id',$id)->update($update);
            }
            $i++;
            return 'ok';
        });
    }
}